package com.bangyu.monitor.core.mqtt;

import com.bangyu.monitor.core.common.constant.ConstantEnum;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;

import java.util.Arrays;
import java.util.List;

/**
 * @Auther: zhangxue
 * @Date: 19/4/12 15:12
 * @Description: 数据帧对象
 */
@Slf4j
public class ErayicFrame {

    /// Erayic帧最大长度
    public static int ERAYIC_PROTOCL_CLASS_BUFFER_LEN = 5000;
    /// Erayic帧头 偏移量
    public static int ERAYIC_PROTOCL_HEAD_OFFSET = 0;
    /// Erayic帧头 字节数
    public static int ERAYIC_PROTOCL_HEAD_BYTES = 2;
    /// Erayic 帧长度 偏移量
    public static int ERAYIC_PROTOCL_FRAME_LEN_OFFSET = 2;
    /// Erayic 帧长度 字节数
    public static int ERAYIC_PROTOCL_FRAME_LEN_BYTES = 2;
    /// Erayic 帧CLASS ID 偏移量
    public static int ERAYIC_PROTOCL_CLASSID_OFFSET = 4;
    /// Erayic 帧CLASS ID  字节数
    public static int ERAYIC_PROTOCL_CLASSID_BYTES = 2;
    /// Erayic 帧Payload 偏移量
    public static int ERAYIC_PROTOCL_PAYLOAD_OFFSET = 6;
    /// Erayic帧最小长度
    public static int ERAYIC_PROTOCL_FRAME_LEN_MIN = 8;//2(head)+2(len)+2(classid)+2(crc)=8(no payload)
    /// Erayic帧最大长度
    public static int ERAYIC_PROTOCL_FRAME_LEN_MAX = 4992;//248+8=256
    /// Erayic帧CRC校验码字节数
    public static int ERAYIC_PROTOCL_CRC_CODE_BYTES = 2;

    /// 头
    public static byte[] Head = new byte[] { (byte)0xb5, 0x72 };
    /// 长度
    public byte[] FrameLen = new byte[] { 1, 1 };
    /// classid(ushort)
    public int classId;
    /// classid(byte[2])
    public byte[] byteClassId = new byte[] { 0x00, 0x00 };
    /// 有效载荷
    public byte[] payload = new byte[] { };

    //通道数据
    public List<OneChSensor> chSensors = Lists.newArrayList();


    public ErayicFrame(byte[] buf)
    {
        log.info("字节数"+buf.length);
        if (buf.length < ERAYIC_PROTOCL_FRAME_LEN_MIN || buf.length > ERAYIC_PROTOCL_CLASS_BUFFER_LEN)
        {
            payload = null;
        }else {
            ///判断Header 为0xb5 0x72
            if (buf[ERAYIC_PROTOCL_HEAD_OFFSET] == Head[0] && buf[ERAYIC_PROTOCL_HEAD_OFFSET + 1] == Head[1]) {
                ///将代表帧长度的2个自己存放FrameLen，将代表classId的两个字节存放ByteClassId
                FrameLen = Arrays.copyOfRange(buf,ERAYIC_PROTOCL_FRAME_LEN_OFFSET,ERAYIC_PROTOCL_FRAME_LEN_BYTES+ERAYIC_PROTOCL_FRAME_LEN_OFFSET);
                byteClassId = Arrays.copyOfRange(buf,ERAYIC_PROTOCL_CLASSID_OFFSET,ERAYIC_PROTOCL_CLASSID_OFFSET+ERAYIC_PROTOCL_CLASSID_BYTES);
                ///第一个字节*16的2次方+第二个字节代表啥？
                classId =  (byteClassId[0] * 256 + byteClassId[1]);
                int len = (FrameLen[0] * 256 + FrameLen[1]);

                if (len < ERAYIC_PROTOCL_FRAME_LEN_MAX) {
                    //暂时不明白校验方法
                    //if (DataCheck.usMBCRC16(buf.Skip(ERAYIC_PROTOCL_FRAME_LEN_OFFSET).ToArray(), len + 2) == 0)
                    {
                        ///结合mqtt word看len少算了2位，所以不用减去header的2位了
                        int payloadlen = len - ERAYIC_PROTOCL_FRAME_LEN_BYTES - ERAYIC_PROTOCL_CLASSID_BYTES;
                        payload = new byte[payloadlen];
                        payload = Arrays.copyOfRange(buf,ERAYIC_PROTOCL_PAYLOAD_OFFSET,ERAYIC_PROTOCL_PAYLOAD_OFFSET+payloadlen);
                    }
                }
                createSensorList();
            }
        }
    }

    //构建通道数据列表
    public void createSensorList(){
        ///节点号，对应word叫设备号，但参数id不是设备id么？
        byte coilNo = payload[0];
        ///开始通道
        byte  startChannel = payload[1];
        byte chNums = payload[2];///通道数量
        System.out.println(String.format("节点号%s,开始通道%s,通道数量%s",coilNo,startChannel,chNums));
        ///word里只有payload[3]代表字节数
        byte byteNums_Low = payload[3];
        byte byteNums_High = payload[4];

        int byteNums = byteNums_High * 256 + byteNums_Low;

        OneChSensor a = null;
        ///通道数据,每四个字节一组
        byte[] sensorata = Arrays.copyOfRange(payload,5,payload.length);

        byte[] buf = new byte[4];
        for (int i = 0; i < byteNums; i += 4){
            buf = Arrays.copyOfRange(sensorata,i,i+4);
            OneChSensor x = new OneChSensor(buf, (byte)((i / 4) + startChannel));
            a = x;
            if (a.getSensorTyp() != ConstantEnum.Sensortype.SENSOR_ERR.getValue())
            {
                chSensors.add(a);
            }
        }

//        List<OneChSensor> sensors0 = (List)CollectionUtils.select(chSensors,
//                (Object o)->{return ((OneChSensor)o).sensorTyp==30;});
//
//        List<OneChSensor> sensors1 = (List)CollectionUtils.select(chSensors,
//                (Object o)->{return ((OneChSensor)o).sensorTyp==31;});
//
//        List<OneChSensor> sensors2 = (List)CollectionUtils.select(chSensors,
//                (Object o)->{return ((OneChSensor)o).sensorTyp==31;});
//
//        List<OneChSensor> sensors3 = (List)CollectionUtils.select(chSensors,
//                (Object o)->{return ((OneChSensor)o).sensorTyp==32;});
//
//        List<OneChSensor> sensors4 = (List)CollectionUtils.select(chSensors,
//                (Object o)->{return ((OneChSensor)o).sensorTyp==33;});
//
//        List<OneChSensor> sensors5 = (List)CollectionUtils.select(chSensors,
//                (Object o)->{return ((OneChSensor)o).sensorTyp==38;});

    }

    public List<OneChSensor> getChSensors() {
        return chSensors;
    }
}
